package com.alibaba.citrus.ots.application.report.ability.facade.job;

import com.alibaba.citrus.ots.application.report.ability.repository.BaseDataQueryRepository;
import com.alibaba.citrus.ots.application.report.ability.repository.BaseInventoryImportRepository;
import com.alibaba.citrus.ots.application.report.ability.utils.DomUtil;
import com.alibaba.citrus.ots.application.report.ability.utils.PageRecordUtil;
import com.alibaba.citrus.ots.common.annotation.ProcessInvoker;
import com.alibaba.citrus.ots.common.util.DateUtils;
import com.alibaba.cz.base.tool.StringUtil;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.middleware.cache.runtime.service.EpochCacheService;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.model.dto.CategoryGetCurrentCategoryByIdRequest;
import com.epoch.app.bcorder.model.dto.QueryCargoZoneByIdOnlyOneRequest;
import com.epoch.app.bcorder.model.dto.QueryCargoZoneByIdOnlyOneResponse;
import com.epoch.app.bcorder.model.dto.ScItemSDO;
import com.epoch.app.bcorder.model.dto.SearchCargoZoneListRequest;
import com.epoch.app.bcorder.model.dto.SearchCargoZoneListResponse;
import com.epoch.app.bcorder.model.dto.SearchScItemRequest;
import com.epoch.app.bcorder.model.dto.SearchWarehouseForPullForPlatformRequest;
import com.epoch.app.bcorder.model.dto.SearchWarehouseForPullForPlatformResponse;
import com.epoch.app.bcorder.model.dto.WarehouseInfo;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.bcorder.service.BcOrderService;
import com.epoch.app.bcorder.service.UnifiedInventoryService;
import com.epoch.app.bcots.contants.BcOtsConstants;
import com.epoch.app.crplatformenhance.model.dto.GetTopOrganizationListRequest;
import com.epoch.app.crplatformenhance.sdo.CustomerAddressSDO;
import com.epoch.app.crplatformenhance.service.CrPlatformEnhanceService;
import com.epoch.app.crunifiedinventory.model.dto.WarehouseInfoDTO;
import com.epoch.app.crunifiedinventory.model.dto.WarehouseInventory;
import com.epoch.app.otsapplicationreportsdk.inventorysync.dto.DoHandle2Request;
import com.epoch.app.otsapplicationreportsdk.inventorysync.dto.DoHandlerRequest;
import com.epoch.app.otsapplicationreportsdk.inventorysync.dto.ReAnalysisReportRequest;
import com.epoch.app.otsapplicationreportsdk.inventorysync.dto.RefreshStoreInventoryChannelCodeRequest;
import com.epoch.app.otsapplicationreportsdk.inventorysync.service.InventorySyncService;
import com.epoch.app.otsapplicationreportsdk.model.dto.GoodsDO;
import com.epoch.app.otsapplicationreportsdk.model.enums.InventoryTypeEnum;
import com.epoch.app.otsapplicationreportsdk.storeinventorystats.dto.LoadListRequest;
import com.epoch.app.otsapplicationreportsdk.storeinventorystats.model.StoreInventoryStats;
import com.epoch.app.otsapplicationreportsdk.storeinventorystats.service.StoreInventoryStatsService;
import com.epoch.app.otsapplicationreportsdk.warehouseinventorystats.dto.BatchUpdateRequest;
import com.epoch.app.otsapplicationreportsdk.warehouseinventorystats.service.WarehouseInventoryStatsService;
import com.epoch.app.otsunifiedinventory.model.dto.GetWarehouseIdForAnalysisRequest;
import com.epoch.app.otsunifiedinventory.model.dto.WarehouseIds;
import com.epoch.app.otsunifiedinventory.service.OtsUnifiedInventoryService;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

@Primary
@Component
public class InventorySyncJob implements InventorySyncService {

    private static Log log = Log.getLogger(InventorySyncJob.class);

    private static final int PAGE_NO_1 = 1;

    private static final int PAGE_SIZE_400 = 400;
    private static final String SALE_ORG_CODE_EC = "1171";
    private static final String SALE_ORG_CODE_VIP = "6140";
    @Resource(name = "scItemsQueryTaskExecutor")
    ThreadPoolTaskExecutor scItemsQueryTaskExecutor;

    @Autowired
    Map<String, BaseInventoryImportRepository> importRepositoryMap;

    @Resource
    BaseDataService baseDataService;

    @Resource
    BcOrderService bcOtsService;

    @Resource
    WarehouseInventoryStatsService warehouseInventoryStatsService;
    @Resource
    UnifiedInventoryService unifiedInventoryService;

    @Resource
    CrPlatformEnhanceService otsPlatformEnhanceService;
    @Resource
    OtsUnifiedInventoryService otsUnifiedInventoryService;

    @Resource
    BaseDataQueryRepository baseDataQueryRepository;
    @Resource
    EpochCacheService epochCacheService;
    private final String JOB_RUNNING_TAG="InventorySyncService_";
    private final String JOB_RUNNING_STATUS="RUNNING";
    private final String JOB_STOP_STATUS="STOP";
    @Override
    public Object searchCargoZoneListForRreport() {
        Object object = warehouseInventoryStatsService.getAllWarehouseAreaId();
        JSONObject json = (JSONObject)JSON.toJSON(object);
        JSONArray array = json.getJSONArray("result");
        for (Object data : array) {
            JSONObject o = (JSONObject)JSON.toJSON(data);
            String warehouseAreaId = o.getString("warehouseAreaId");
            QueryCargoZoneByIdOnlyOneRequest request = new QueryCargoZoneByIdOnlyOneRequest();
            request.setCargoZoneIdList(Arrays.asList(warehouseAreaId));
            QueryCargoZoneByIdOnlyOneResponse response = unifiedInventoryService.queryCargoZoneByIdOnlyOne(request);
            if (response != null && response.getResult() != null) {
                JSONObject result = (JSONObject)JSON.toJSON(response.getResult());
                String saleOrgId = result.getString("saleOrgId");
                String bizUnitId = getBizUnitId(saleOrgId);
                BatchUpdateRequest batchUpdateRequest = new BatchUpdateRequest();
                batchUpdateRequest.setBizUnitId(bizUnitId);
                batchUpdateRequest.setWarehouseAreaId(warehouseAreaId);
                Object objResult = warehouseInventoryStatsService.batchUpdate(batchUpdateRequest);
            }
        }
        return null;
    }

    private String getBizUnitId(String saleOrgId) {
        if (org.apache.commons.lang.StringUtils.isBlank(saleOrgId)) {
            return "-1";
        }
        GetTopOrganizationListRequest request = new GetTopOrganizationListRequest();
        request.setId(saleOrgId);
        request.setType(103);
        try {
            Result<List<com.epoch.app.crplatformenhance.model.dto.TopOrganizationListResponse>> result
                = otsPlatformEnhanceService.getTopOrganizationList(request);
            if (result != null && CollectionUtils.isNotEmpty(result.getResult())) {
                List<com.epoch.app.crplatformenhance.model.dto.TopOrganizationListResponse> responseList = result
                    .getResult().stream().filter(x -> x.getType().equals(103)).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(responseList)) {
                    return responseList.get(0).getId();
                }
            }
        } catch (Exception e) {
            log.error("getTopOrganizationList_error={}", e);
        }
        return "-1";
    }

    @Override
    @ProcessInvoker
    public Result<Boolean> doHandler(DoHandlerRequest doHandlerRequest) {
        InventoryTypeEnum typeEnum = InventoryTypeEnum.of(doHandlerRequest.getType());
        if (typeEnum == null) {
            log.warn("InventorySyncServiceImpl_doHandlerRequest_not_valid");
            return Result.fail("-1", "输入参数不合法");
        }
        if(!canRunJob(doHandlerRequest.getType())){
            return Result.fail("-1", "已有任务执行中");
        }
        try {
            startRunning(doHandlerRequest.getType());
            //如果是电商的 走新逻辑
            if (InventoryTypeEnum.EC_SHARE.getType().intValue() == doHandlerRequest.getType().intValue()) {
                return doHandleNew(doHandlerRequest, getEcWarehouseIds());
            }
            if (InventoryTypeEnum.STORE.getType().intValue() == doHandlerRequest.getType().intValue()) {
                //获取中台库存表里的仓库
                GetWarehouseIdForAnalysisRequest request = new GetWarehouseIdForAnalysisRequest();
                request.setType(InventoryTypeEnum.STORE.getType());
                WarehouseIds allwarehouseAreaIds = otsUnifiedInventoryService.getWarehouseIdForAnalysis(request);
                if (Objects.isNull(allwarehouseAreaIds) || CollectionUtils.isEmpty(allwarehouseAreaIds.getWarehouseAreaIds())) {
                    return Result.success(true);
                }
                return doHandleNew(doHandlerRequest, allwarehouseAreaIds.getWarehouseAreaIds());
            }
            return Result.success(true);
        } catch (Exception e) {
            log.error("InventorySyncJob_doHandler_error={}", e);
            return Result.fail("-1", e.getMessage());
        } finally {
            stopJob(doHandlerRequest.getType());
        }
    }

    private boolean canRunJob(int type){
        String isRunning=epochCacheService.get(BcOtsConstants.REDIS_CACHE_CODE(),JOB_RUNNING_TAG+type);
        if(StringUtils.isNotBlank(isRunning)&&JOB_RUNNING_STATUS.equals(isRunning)) {
            log.info("The InventorySyncJob is running,type=:{}", type);
            return false;
        }
       return true;
    }
    private void startRunning(int type){
        epochCacheService.put(BcOtsConstants.REDIS_CACHE_CODE(),JOB_RUNNING_TAG+type,JOB_RUNNING_STATUS,1800L,TimeUnit.SECONDS);
    }
    private void stopJob(int type){
        epochCacheService.put(BcOtsConstants.REDIS_CACHE_CODE(),JOB_RUNNING_TAG+type,JOB_STOP_STATUS,1800L,TimeUnit.SECONDS);
    }
    //取商品总数
    private int getGoodsTotal() {
        SearchScItemRequest request = new SearchScItemRequest();
        Map<String, Object> searchReqDTO = new HashMap<>();
        searchReqDTO.put("businessType", "11");//常温
        searchReqDTO.put("type", 0);//非组合货品
        searchReqDTO.put("statusList", Lists.newArrayList("1", "-1"));
        request.setSearchReqDTO(searchReqDTO);
        request.setPageSize(PAGE_SIZE_400);
        request.setPageNum(PAGE_NO_1);
        return baseDataService.searchScItem(request).getTotal();
    }

    //并行拉取所有商品
    private Map<String, GoodsDO> getGoodsInfo() {
        List<Future<List<ScItemSDO>>> futureList = Lists.newArrayList();
        int totalCnt = getGoodsTotal();
        int totalPage = totalCnt / PAGE_SIZE_400;
        if (totalCnt % PAGE_SIZE_400 > 0) {
            totalPage++;
        }
        for (int pageNo = 1; pageNo <= totalPage; pageNo++) {
            int finalPageNo = pageNo;
            CompletableFuture<List<ScItemSDO>> future = CompletableFuture.supplyAsync(() -> {
                Result<List<ScItemSDO>> listResult = null;
                SearchScItemRequest request = new SearchScItemRequest();
                Map<String, Object> searchReqDTO = new HashMap<>();
                searchReqDTO.put("businessType", "11");//常温
                searchReqDTO.put("type", 0);//非组合货品
                searchReqDTO.put("statusList", Lists.newArrayList("1", "-1"));
                request.setSearchReqDTO(searchReqDTO);
                request.setPageSize(PAGE_SIZE_400);
                request.setPageNum(finalPageNo);
                try {
                    listResult = baseDataService.searchScItem(request);
                    if (listResult == null || CollectionUtils.isEmpty(listResult.getResult())) {
                        return Lists.newArrayList();
                    }
                } catch (Exception e) {
                    log.error("多线程拉取库存数据异常", e);
                }
                List<ScItemSDO> goodsSubList = listResult.getResult();
                return goodsSubList;
            }, scItemsQueryTaskExecutor);
            futureList.add(future);
        }
        List<ScItemSDO> result = new ArrayList<>();
        try {
            for (Future<List<ScItemSDO>> future : futureList) {
                List<ScItemSDO> goodsSubList = future.get();
                result.addAll(goodsSubList);
            }
        } catch (Exception e) {
            log.error("获取多线程查询结果异常", e);
        }
        log.info("inventorySyncJob_getGoodsInfo_size={}", result.size());
        return buildGoodsInfo(result);
    }

    //构建商品信息
    private Map<String, GoodsDO> buildGoodsInfo(List<ScItemSDO> scItemSDOS) {
        Map<String, GoodsDO> result = new HashMap<>();
        List<String> categoryList = scItemSDOS.stream().map(x -> x.getLeafCategoryId()).distinct().collect(
            Collectors.toList());
        Map<String, Map<String, String>> category = getCategoryInfo(categoryList);
        for (ScItemSDO scItemSDO : scItemSDOS) {
            String key = scItemSDO.getScItemId();
            GoodsDO value = buildGoodsDO(scItemSDO, category);
            result.put(key, value);
        }
        return result;
    }

    private GoodsDO buildGoodsDO(ScItemSDO scItemSDO, Map<String, Map<String, String>> category) {
        GoodsDO goodsDO = new GoodsDO();
        goodsDO.setGoodsId(scItemSDO.getScItemId());
        goodsDO.setOuterItemId(scItemSDO.getOuterId());
        goodsDO.setGoodsName(scItemSDO.getTitle());
        Map<String, String> features = scItemSDO.getFeatures();
        String guaranteePeriod = features.get("guaranteePeriod");
        if (StringUtils.isNotBlank(guaranteePeriod)) {
            goodsDO.setGuaranteePeriod(Integer.valueOf(guaranteePeriod));
        } else {
            goodsDO.setGuaranteePeriod(0);
        }
        String categoryId = scItemSDO.getLeafCategoryId();
        goodsDO.setCategoryId(StringUtils.isBlank(categoryId) ? "_" : categoryId);
        Map<String, String> map = category.get(categoryId);
        if (map == null || map.isEmpty()) {
            goodsDO.setRootCategoryName("_");
            goodsDO.setCategoryName("_");
            goodsDO.setRootCategoryId("_");
        } else {
            goodsDO.setCategoryName(
                StringUtils.isBlank(map.get("leafCategoryName")) ? "_" : map.get("leafCategoryName"));
            goodsDO.setRootCategoryId(StringUtils.isBlank(map.get("rootCategoryId")) ? "_" : map.get("rootCategoryId"));
            goodsDO.setRootCategoryName(
                StringUtils.isBlank(map.get("rootCategoryName")) ? "_" : map.get("rootCategoryName"));
        }
        return goodsDO;
    }

    //取类目名称信息
    private Map<String, Map<String, String>> getCategoryInfo(List<String> categoryIds) {
        Map<String, Map<String, String>> category = new HashMap<>();
        for (String categoryId : categoryIds) {
            if (StringUtils.isBlank(categoryId)) {
                continue;
            }
            CategoryGetCurrentCategoryByIdRequest categoryGetCurrentCategoryByIdRequest
                = new CategoryGetCurrentCategoryByIdRequest();
            categoryGetCurrentCategoryByIdRequest.setId(categoryId);
            Map resultMap = (Map)bcOtsService.categoryGetCurrentCategoryById(categoryGetCurrentCategoryByIdRequest);
            Map categoryMap = (Map)resultMap.get("result");
            if (MapUtils.isNotEmpty(categoryMap)) {
                Map<String, String> map = new HashMap<>();
                List<String> path = (List)categoryMap.get("path");
                List<String> idPath = (List)categoryMap.get("idPath");
                //叶子类目
                map.put("leafCategoryId", (String)categoryMap.get("catId"));
                map.put("leafCategoryName", (String)categoryMap.get("name"));
                //一级类目
                map.put("rootCategoryId", idPath.get(1));
                map.put("rootCategoryName", path.get(1));
                category.put(categoryId, map);
            }
        }
        return category;
    }

    /**
     * 逻辑仓走的  批次库存定时任务
     * 入参partSize当前弃用！！！
     * @param doHandle2Request
     * @return
     */
    @Override
    @ProcessInvoker
    public Object doHandle2(DoHandle2Request doHandle2Request) {
        InventoryTypeEnum typeEnum = InventoryTypeEnum.of(doHandle2Request.getType());
        if (typeEnum == null) {
            log.warn("InventorySyncServiceImpl_doHandlerRequest_not_valid");
            return Result.fail("-1", "输入参数不合法");
        }
        if (!typeEnum.getType().equals(2)) {
            log.warn("InventorySyncServiceImpl_doHandlerRequest_not_valid");
            return Result.fail("-1", "输入参数不合法");
        }
        if(!canRunJob(doHandle2Request.getType())){
            return Result.fail("-1", "已有任务执行中");
        }
        try {
            startRunning(doHandle2Request.getType());
            StopWatch stopWatch = new StopWatch("doHandler2");
            // 取所有商品信息
            stopWatch.start("getGoodsInfo");
            Map<String, GoodsDO> goodsDOMap = getGoodsInfo();
            stopWatch.stop();
            log.info("InventorySyncServiceImpl_goodsDOMap_size={},type2={},use_time={}s", goodsDOMap.size(),doHandle2Request.getType(), stopWatch.getTotalTimeSeconds());

            BaseInventoryImportRepository repository = importRepositoryMap.get(typeEnum.getTask());
            boolean firstSyncOfToday = repository.firstSyncOfToday();

            stopWatch.start("getInventoryList");
            //通过查询cr_business_inventory批次库存表去重warehouse_area_id  查到所有的仓库
            GetWarehouseIdForAnalysisRequest request = new GetWarehouseIdForAnalysisRequest();
            request.setType(doHandle2Request.getType());
            WarehouseIds allwarehouseAreaIds = otsUnifiedInventoryService.getWarehouseIdForAnalysis(request);
            if (Objects.isNull(allwarehouseAreaIds) || CollectionUtils.isEmpty(allwarehouseAreaIds.getWarehouseAreaIds())) {
                return Result.success(true);
            }
            // 从中台并行拉取数据. 按仓库分组进行，防止全部库存加载到内存导致内存太高
            Map<String, WarehouseInfoDTO> warehouseAreaMap = baseDataQueryRepository.getLogicZoneInfo(allwarehouseAreaIds.getWarehouseAreaIds());
            Map<String, List<String>> orgWarehouses = groupByOrgId(warehouseAreaMap);//销售组织,逻辑仓idList
            Iterator<Entry<String, List<String>>> entryIterator = orgWarehouses.entrySet().iterator();

            //查询所有电商仓 1171和6140销售组织的逻辑仓
            List<String> ecWarehouseIds = getEcWarehouseIdsByOrgCode(SALE_ORG_CODE_EC);
            ecWarehouseIds.addAll(getEcWarehouseIdsByOrgCode(SALE_ORG_CODE_VIP));
            log.info("inventorySyncReport_doHandle2_ecWarehouseIds6140_size={},ecWarehouseIds={}", ecWarehouseIds.size(),JSONObject.toJSONString(ecWarehouseIds));

            int totalBatchIntentory = 0;
            while (entryIterator.hasNext()) {
                Entry<String, List<String>> x = entryIterator.next();
                List<String> warehouseAreaIds = x.getValue();
                //SQL直接统计库存  cr_business_inventory批次库存表
                List<WarehouseInventory> inventoryList = repository.getInventoryList(warehouseAreaIds, doHandle2Request.getSize());
                log.info("inventorySyncReport_doHandle2_getInventoryList_request_saleOrgId={},warehouseAreaIds={},result_warehouseInventoryList_size={}", x.getKey(),x.getValue(),inventoryList.size());
                if (CollectionUtils.isEmpty(inventoryList)) {
                    continue;
                }

                //过滤掉电商仓库存
                List<WarehouseInventory> importInventoryList = new ArrayList<>();
                for (WarehouseInventory inventory : inventoryList) {
                    WarehouseInfoDTO warehouseInfoDTO = warehouseAreaMap.get(inventory.getWarehouseAreaId());
                    if (warehouseInfoDTO != null) {
                        inventory.setWarehouseName(warehouseInfoDTO.getName());
                    }
                    if (!isEcWarehouse(inventory.getWarehouseAreaId(), ecWarehouseIds)) {
                        importInventoryList.add(inventory);
                    }
                }
                log.info("inventorySyncReport_doHandle2_getInventoryList_filterResult_size={}", importInventoryList.size());
                totalBatchIntentory = totalBatchIntentory + importInventoryList.size();

                List<String> importWarehouseAreaIds = warehouseAreaIds.stream().filter(id->!isEcWarehouse(id, ecWarehouseIds)).collect(Collectors.toList());

                // 数据入库
                repository.doImportData(importInventoryList, importWarehouseAreaIds, goodsDOMap, firstSyncOfToday);
            }
            stopWatch.stop();
            log.info("inventorySyncReport_doHandler2_pull_inventoryList_size={},type={},use_time={}s", totalBatchIntentory,typeEnum.getType(),stopWatch.getTotalTimeSeconds());
            log.info("inventorySyncReport_doHandler2_stopWatch_prettyPrint={}", stopWatch.prettyPrint());
            return Result.success(true);
        } catch (Exception e) {
            stopJob(doHandle2Request.getType());
            log.error("InventorySyncJob_doHandler_error={}", e);
            return Result.fail("-1", e.getMessage());
        } finally {
            stopJob(doHandle2Request.getType());
        }
    }

    /**
     * 电商仓 门店仓走的逻辑
     */
    public Result<Boolean> doHandleNew(DoHandlerRequest doHandlerRequest, List<String> targetWarehouseIds) {
        InventoryTypeEnum typeEnum = InventoryTypeEnum.of(doHandlerRequest.getType());
        if (typeEnum == null) {
            log.warn("InventorySyncServiceImpl_doHandlerRequest_not_valid");
            return Result.fail("-1", "输入参数不合法");
        }
        if (CollectionUtils.isEmpty(targetWarehouseIds)) {
            return Result.success(true);
        }
        try {
            Map<String, GoodsDO> goodsDOMap = getGoodsInfo();
            BaseInventoryImportRepository repository = importRepositoryMap.get(typeEnum.getTask());
            boolean firstSyncOfToday = repository.firstSyncOfToday();
            StopWatch stopWatch = new StopWatch("InventorySyncJob_doHandleNew");
            stopWatch.start("getInventoryList");
            //查到所有的仓库
            Map<String, WarehouseInfo> warehouseAreaMap = getWarehouseInfo(targetWarehouseIds);
            //按仓库分组，防止全部库存加载到内存导致内存太高
            List<List<String>> partitionWarehouseAreaIds = Lists.partition(targetWarehouseIds, 50);
            int totalBatchIntentory = 0;
            for (List<String> warehouseAreaIds : partitionWarehouseAreaIds) {
                List<WarehouseInventory> inventoryList = repository.getInventoryList(warehouseAreaIds, 1000);
                if (CollectionUtils.isEmpty(inventoryList)) {
                    continue;
                }
                totalBatchIntentory = totalBatchIntentory + inventoryList.size();
                // 数据入库
                for (WarehouseInventory warehuoseTmp : inventoryList) {
                    WarehouseInfo warehouseInfoDTO = warehouseAreaMap.get(warehuoseTmp.getWarehouseAreaId());
                    if (warehouseInfoDTO != null) {
                        warehuoseTmp.setWarehouseName(warehouseInfoDTO.getName());
                    }
                }
                repository.doImportData(inventoryList, warehouseAreaIds, goodsDOMap, firstSyncOfToday);
            }
            stopWatch.stop();
            log.info("doHandleNew_pull_inventoryList_size={},type={},use_time={}s", totalBatchIntentory,typeEnum.getType(),stopWatch.getTotalTimeSeconds());
            return Result.success(true);
        } catch (Exception e) {
            log.error("InventorySyncJob_doHandler_error={}", e);
            return Result.fail("-1", e.getMessage());
        }
    }

    private Map<String, WarehouseInfo> getWarehouseInfo(List<String> targetWarehouseIds) {
        List<List<String>> partWarehouseList = Lists.partition(targetWarehouseIds, 1000);
        List<WarehouseInfo> list = new ArrayList<>();
        for (List<String> parList : partWarehouseList) {
            SearchCargoZoneListRequest request = new SearchCargoZoneListRequest();
            request.setWarehouseAreaIds(parList);
            request.setLimit(1000);
            request.setStart(0);
            SearchCargoZoneListResponse response = unifiedInventoryService.searchCargoZoneList(request);
            if(Objects.nonNull(response) && CollectionUtils.isNotEmpty(response.getResult())){
                list.addAll(response.getResult());
            }
        }
        Map<String, WarehouseInfo> warehouseMap = CollectionUtils.isNotEmpty(list) ? list.stream().collect(
            Collectors.toMap(WarehouseInfo::getId, Function.identity(), (v1, v2) -> v1)) : new HashMap<String, WarehouseInfo>();
        return warehouseMap;
    }

    public Map<String, List<String>> groupByOrgId(Map<String, WarehouseInfoDTO> warehouseAreaMap) {
        List<WarehouseInfoDTO> warehouseInfoDTOS = warehouseAreaMap.entrySet().stream().map(x -> x.getValue()).collect(Collectors.toList());
        Map<String, List<String>> mapOrg = new HashMap<>();
        for (WarehouseInfoDTO x : warehouseInfoDTOS) {
            if (mapOrg.containsKey(x.getSaleOrgId())) {
                mapOrg.get(x.getSaleOrgId()).add(x.getId());
            } else {
                List<String> childs = new ArrayList<>();
                childs.add(x.getId());
                mapOrg.put(x.getSaleOrgId(), childs);
            }
        }
        return mapOrg;
    }

    //取电商逻辑仓
    private List<String> getEcWarehouseIds() {
        int PAGE_SIZE_200 = 200;
        SearchWarehouseForPullForPlatformRequest request = new SearchWarehouseForPullForPlatformRequest();
        request.setOrgCode("1171");
        request.setStart(0);
        request.setLimit(PAGE_SIZE_200);
        SearchWarehouseForPullForPlatformResponse response = bcOtsService.searchWarehouseForPullForPlatform(request);
        if (response == null || CollectionUtils.isEmpty(response.getResult())) {
            return Lists.newArrayList();
        }
        List result = response.getResult();
        int totalCnt = response.getTotal();
        if (totalCnt > PAGE_SIZE_200) {
            int totalPage = totalCnt / PAGE_SIZE_200;
            if (totalCnt % PAGE_SIZE_200 > 0) {
                totalPage++;
            }
            //list里已经添加了第0页的result，从第1页开始查 复制的远古代码 为了安全不改了
            for (int pageNo = 1; pageNo < totalPage; pageNo++) {
                request.setStart(pageNo * PAGE_SIZE_200);
                response = bcOtsService.searchWarehouseForPullForPlatform(request);
                if (response != null && CollectionUtils.isNotEmpty(response.getResult())) {
                    result.addAll(response.getResult());
                }
            }
        }
        List<String> warehouseAreaIds = new ArrayList<>();
        for (Object o : result) {
            JSONObject json = (JSONObject)JSONObject.toJSON(o);
            warehouseAreaIds.add(json.getString("id"));
        }
        return warehouseAreaIds;
    }

    //取电商逻辑仓
    private List<String> getEcWarehouseIdsByOrgCode(String orgCode) {
        SearchWarehouseForPullForPlatformRequest request = new SearchWarehouseForPullForPlatformRequest();
        request.setOrgCode(orgCode);
        request.setStart(0);
        request.setLimit(PAGE_SIZE_400);
        SearchWarehouseForPullForPlatformResponse response = bcOtsService.searchWarehouseForPullForPlatform(request);
        log.info("warehouseInventoryImportImpl_getEcWarehouse_request={},size={}", JSON.toJSONString(request),
            response.getTotal());
        if (response == null || CollectionUtils.isEmpty(response.getResult())) {
            return Lists.newArrayList();
        }
        List result = response.getResult();
        int totalCnt = response.getTotal();
        if (totalCnt > PAGE_SIZE_400) {
            int totalPage = totalCnt / PAGE_SIZE_400;
            if (totalCnt % PAGE_SIZE_400 > 0) {
                totalPage++;
            }
            for (int pageNo = 1; pageNo < totalPage; pageNo++) {
                request.setStart(pageNo * PAGE_SIZE_400);
                response = bcOtsService.searchWarehouseForPullForPlatform(request);
                if (response != null && CollectionUtils.isNotEmpty(response.getResult())) {
                    result.addAll(response.getResult());
                }
            }
        }
        List<String> warehouseAreaIds = new ArrayList<>();
        for (Object o : result) {
            JSONObject json = (JSONObject)JSONObject.toJSON(o);
            warehouseAreaIds.add(json.getString("id"));
        }
        return warehouseAreaIds;
    }

    //判断是否为电商逻辑仓
    private boolean isEcWarehouse(String warehouseId, List<String> warehouseIds) {
        return warehouseIds.contains(warehouseId);
    }

    @Override
    public Result<Void> reAnalysisReport(ReAnalysisReportRequest reAnalysisReportRequest) {
        InventoryTypeEnum typeEnum = InventoryTypeEnum.of(reAnalysisReportRequest.getType());
        if (typeEnum == null) {
            log.warn("InventorySyncServiceImpl_doHandlerRequest_not_valid");
            return Result.fail("-1", "输入参数不合法");
        }
        BaseInventoryImportRepository repository = importRepositoryMap.get(typeEnum.getTask());
        repository.reAnalysisReport(reAnalysisReportRequest.getStatisticalDate());
        return Result.success(null);
    }


    @Resource
    StoreInventoryStatsService storeInventoryStatsService;

    @Override
    public Result<Void> refreshStoreInventoryChannelCode(RefreshStoreInventoryChannelCodeRequest refreshStoreInventoryChannelCodeRequest) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date beginStatisticalDate = null;
        Date endStatisticalDate = null;
        try {
            beginStatisticalDate = format.parse(refreshStoreInventoryChannelCodeRequest.getStartDate());
            endStatisticalDate = format.parse(refreshStoreInventoryChannelCodeRequest.getEndDate());
        } catch (ParseException e) {
            return Result.fail("","入参日期格式错误");
        }
        if(beginStatisticalDate.getTime()>endStatisticalDate.getTime()){
            return Result.fail("","开始统计日期大于结束统计日期");
        }
        int betweenDays = DomUtil.getBetweenDays(refreshStoreInventoryChannelCodeRequest.getStartDate(),refreshStoreInventoryChannelCodeRequest.getEndDate());
        if(betweenDays >31 ){
            return Result.fail("","开始结束统计日期间隔过大");
        }

        String statisticalDate = refreshStoreInventoryChannelCodeRequest.getStartDate();

        for(int i = 1; i<=31; i++) {
            if (i != 1) {
                statisticalDate = DomUtil.getRollbackDate(DateUtils.parse(statisticalDate), 1);
            }
            if (statisticalDate.equals(DomUtil.getRollbackDate(endStatisticalDate, 1))) {
                break;
            }

            PageRecordUtil pageUtil = new PageRecordUtil();
            pageUtil.resetPageParam();
            LoadListRequest loadListRequest = new LoadListRequest();
            loadListRequest.setStatisticalDate(statisticalDate);
            loadListRequest.setLimit(pageUtil.getPageSize());
            for (int j = 1; j <= pageUtil.getPage(); j++) {
                loadListRequest.setStart(pageUtil.getStart());
                Result<List<StoreInventoryStats>> result = storeInventoryStatsService.loadList(loadListRequest);
                if(j == 1){
                    pageUtil.setTotalPages(result.getTotal());
                }

                List<StoreInventoryStats> statsList = result.getResult();
                List<String> storeIds = statsList.stream().map(x->x.getStoreId()).collect(Collectors.toList());
                Map<String, WarehouseInfo> storeMap = baseDataQueryRepository.getStoreInfo(storeIds);

                List<String> addressIds = storeMap.entrySet().stream().map(x->x.getValue().getAddressCode()).collect(Collectors.toList());
                Map<String, CustomerAddressSDO> addressMap = baseDataQueryRepository.batchQueryCustomerAddress(addressIds);

                Map<String,String> storeSalesOrgMap = new HashMap<>();
                for (Map.Entry<String, WarehouseInfo> entry: storeMap.entrySet()){
                    String storeId = entry.getKey();
                    String addressId = entry.getValue().getAddressCode();
                    String channelCode = StringUtil.isNotEmpty(addressId) && addressMap.get(addressId)!=null?addressMap.get(addressId).getChannelCode():"-1";
                    storeSalesOrgMap.put(storeId, channelCode);
                }

                for (StoreInventoryStats stats:statsList) {
                    String channelCode = storeSalesOrgMap.get(stats.getStoreId());
                    stats.setChannelCode(channelCode);
                    stats.setGmt_modified(new Date());
                    storeInventoryStatsService.update(stats);
                }

                pageUtil.turnPage();
            }
        }

        return Result.success(null);
    }
}
